package com.baicaoyuan.web.service;

import com.baicaoyuan.web.common.MsgUtil;
import com.baicaoyuan.web.common.TimeUtils;
import com.baicaoyuan.web.model.StockDetailsDO;
import com.baicaoyuan.web.model.StockInDO;
import com.baicaoyuan.web.model.StockPeriodDO;
import com.baicaoyuan.web.model.UserDO;
import com.baicaoyuan.web.repository.StockDetailsRepository;
import com.baicaoyuan.web.repository.StockInRepository;
import com.baicaoyuan.web.repository.StockPeriodRepository;
import com.baicaoyuan.web.repository.UserRepository;
import com.baicaoyuan.web.request.br.BStockPeriodRequest;
import com.baicaoyuan.web.response.StockPeriodResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 功能描述：
 *
 * @author 罗富祥
 * 创建时间： 2018/1/4
 */
@Service
public class StockPeriodService {

    @Autowired
    StockPeriodRepository stockPeriodRepository;

    @Autowired
    StockInRepository stockInRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    StockDetailsRepository stockDetailsRepository;

    public List<StockPeriodResponse> getStockPeriod() {
        List<StockPeriodDO> list = this.stockPeriodRepository.getStockPeriod();
        List<StockPeriodResponse> result = new ArrayList<>();
        list.forEach(x -> {
            StockPeriodResponse r = new StockPeriodResponse();
            BeanUtils.copyProperties(x, r);
            result.add(r);
        });

        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(BStockPeriodRequest request) {
        try {
            StockPeriodDO sp = new StockPeriodDO();
            sp.setTitle(request.getTitle());
            Timestamp b = TimeUtils.getMinTime(request.getBeginTime());
            sp.setBeginTime(b);
            Timestamp e = TimeUtils.getMaxTime(request.getEndTime());
            sp.setEndTime(e);
            sp.setMoney(request.getMoney());
            sp.setScore(request.getMoney());
            sp.setDays(TimeUtils.days(b, e));
            StockPeriodDO r = this.stockPeriodRepository.save(sp);
            Objects.requireNonNull(r);
            calcMoney(r);

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }

    /**
     * 计算分红
     */
    private void calcMoney(StockPeriodDO p) {
        List<UserDO> users = userRepository.findByStatusAndCategory("1", "3");


        users.stream().forEach(u -> {

            List<StockInDO> in = stockInRepository.getStockIn(u.getId());

            Long totalNumber = 0L;
            BigDecimal canGetMoney = BigDecimal.ZERO;

            for (StockInDO i : in) {
                BigDecimal number = new BigDecimal(i.getStockNumber());
                long inT = i.getInTime().getTime();
                long bT = p.getBeginTime().getTime();
                long eT = p.getEndTime().getTime();
                totalNumber += i.getStockNumber();

                if (inT > bT && inT < eT) {
                    //股申请时间处于本期时间内，则按比例进行计算
                    long validDays = TimeUtils.days(i.getInTime(), p.getEndTime());
                    BigDecimal rate = new BigDecimal((double) validDays / p.getDays());
                    BigDecimal validMoney = rate.multiply(p.getMoney()).multiply(number);

                    canGetMoney = canGetMoney.add(validMoney);

                } else if (inT < bT) {
                    //股申请时间小于分红最小时间， 说明已经跳过的第一期， 则享受本期全额的分红
                    canGetMoney = canGetMoney.add(p.getMoney().multiply(number));
                }
            }

            StockDetailsDO detailsDO = new StockDetailsDO();
            detailsDO.setUserId(u.getId());
            detailsDO.setUserName(u.getRealName() == null ? u.getUserName() : "");
            detailsDO.setStockPeriodId(p.getId());
            detailsDO.setStockPeriodTitle(p.getTitle());
            detailsDO.setMoney(canGetMoney);
            detailsDO.setMoneyPerStock(p.getMoney());
            detailsDO.setStockNumber(totalNumber);
            stockDetailsRepository.save(detailsDO);

            BigDecimal score = u.getScoreTotal().add(canGetMoney);
            u.setScoreTotal(score);
            userRepository.save(u);

            if (u.getTelephone() != null)
                MsgUtil.stockPeriod(u.getTelephone());
        });
    }

}

